package com.example.security.filter;

import com.example.base.utils.JacksonUtil;
import com.example.security.assembly.LoginFailHandler;
import com.example.security.assembly.LoginSuccessHandler;
import com.example.security.assembly.SystemUserDetailsService;
import com.example.security.assembly.UserPostLoginAuthenticationToken;
import com.example.sys.dto.req.UserLoginReq;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Objects;

@Slf4j
public class PostLoginSecurityFilter extends AbstractAuthenticationProcessingFilter {

    //定义拦截的请求
    private static final AntPathRequestMatcher DEFAULT_ANT_PATH_REQUEST_MATCHER = new AntPathRequestMatcher("/postLogin", "POST");

    public PostLoginSecurityFilter(AuthenticationManager authenticationManager, SystemUserDetailsService userDetailsService) {
        super(DEFAULT_ANT_PATH_REQUEST_MATCHER, authenticationManager);
        this.setAuthenticationFailureHandler(new LoginFailHandler());
        this.setAuthenticationSuccessHandler(new LoginSuccessHandler(userDetailsService.getUserService()));
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException {
        BufferedReader br = request.getReader();
        //读取请求参数
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        IOUtils.copy(br, bos, StandardCharsets.UTF_8.toString());
        String body = bos.toString();
        log.info("登录请求参数: {}", body);
        UserLoginReq req = JacksonUtil.toJavaType(body, UserLoginReq.class);
        if (Objects.isNull(req)){
            throw new AuthenticationServiceException("未检测到登录参数:" + body);
        }
        UserPostLoginAuthenticationToken authRequest = UserPostLoginAuthenticationToken.unauthenticated(req);
        return this.getAuthenticationManager().authenticate(authRequest);
    }
}
